package nl.infodation.emr.pricingservice.business.impl;

import java.util.ArrayList;
import java.util.List;

import nl.infodation.emr.pricingservice.business.RuleBusiness;
import nl.infodation.emr.pricingservice.dao.DAOFactory;
import nl.infodation.emr.pricingservice.data.DomainRuleSearchItem;
import nl.infodation.emr.pricingservice.entity.DomainRule;
import nl.infodation.emr.pricingservice.entity.Environment;
import nl.infodation.emr.pricingservice.entity.SystemValue;
import nl.infodation.emr.pricingservice.ui.page.SessionData;
import nl.infodation.emr.utility.Constants;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.googlecode.genericdao.search.SearchResult;
import com.vaadin.data.util.BeanItem;

/**
 * @author SUCCESS\tungo
 *
 */
public class RuleBusinessImpl implements RuleBusiness {
	
	protected static final Logger LOG = LoggerFactory
			.getLogger(RuleBusinessImpl.class);
		
	private static RuleBusiness instance = null;
	
	private RuleBusinessImpl() { }
	
	public static RuleBusiness getInstance() {
		if (instance == null) {
			instance = new RuleBusinessImpl();
		}
		return instance;
	}
	
	/* (non-Javadoc)
	 * @see nl.infodation.emr.pricingservice.business.RuleBusiness#saveRules(java.util.List)
	 */
	@Override
	public Boolean saveRules(List<DomainRule> rules) {
		return DAOFactory.getDomainRuleDAO().save(rules);
	}

	/* (non-Javadoc)
	 * @see nl.infodation.emr.pricingservice.business.RuleBusiness#saveRule(nl.infodation.emr.pricingservice.entity.DomainRule, java.lang.String)
	 */
	@Override
	public Boolean saveRule(DomainRule rule, String roleName) {
		boolean saved = Boolean.TRUE;
		
		// Process for role
		if (Constants.PROVEA_ROLE.equals(roleName)) {
			if (!rule.getBusLine().equals(Constants.PROVEA_ROLE)) {
				LOG.error(
						"Error saving! the business line must be \"{}\".",
						Constants.PROVEA_ROLE);
				saved = Boolean.FALSE; // failed
			}
		} else if (Constants.AFM_ROLE.equals(roleName)) {
			if (!rule.getBusLine().equals(Constants.AFM_ROLE)) {
				LOG.error(
						"Error saving! the business line must be \"{}\".",
						Constants.AFM_ROLE);
				saved = Boolean.FALSE; // failed
			}
		}
		
		if (saved && DAOFactory.getDomainRuleDAO().save(rule) != null) {
			LOG.info("Domain rule is saved.");
		} else {
			saved = Boolean.FALSE;
		}
		return saved;
	}
	
	@Override
	public List<Long> searchRulesIDs(DomainRuleSearchItem searchData) {
		return DAOFactory.getDomainRuleDAO().findIDs(searchData);
	}

	/* (non-Javadoc)
	 * @see nl.infodation.emr.pricingservice.business.RuleBusiness#findRulesByBusLine(java.lang.String)
	 */
	@Override
	public List<DomainRule> findRulesByBusLine(String busLine) {
		return DAOFactory.getDomainRuleDAO().findByBusLine(busLine);
	}

	/* (non-Javadoc)
	 * @see nl.infodation.emr.pricingservice.business.RuleBusiness#searchRules(java.lang.String, java.lang.Integer, nl.infodation.emr.pricingservice.data.DomainRuleSearchItem, int, int)
	 */
	@SuppressWarnings("rawtypes")
	@Override
	public SearchResult<BeanItem> searchRules(String roleName, Integer environmentId, DomainRuleSearchItem searchData, int startPage,
			int pageSize) {
		SearchResult<BeanItem> result = new SearchResult<>();
		
		if (Constants.PROVEA_ROLE.equals(roleName)) {
			searchData.setBusLine(Constants.PROVEA_ROLE);
		} else if (Constants.AFM_ROLE.equals(roleName)) {
			searchData.setBusLine(Constants.AFM_ROLE);
		}
		
		searchData.setEnvironmentId(environmentId);
		searchData.setCountries(getContriesToSee());
		
		SearchResult<DomainRule> searchResult = DAOFactory.getDomainRuleDAO().searchInPage(searchData, startPage, pageSize);
		
		List<DomainRule> searchList = searchResult.getResult();
		List<BeanItem> list = new ArrayList<>();
		if (searchList != null && searchList.size() > 0) {
			for (DomainRule rule : searchList) {
				list.add(new BeanItem<DomainRule>(rule));
			}
		}
		result.setResult(list);
		result.setTotalCount(searchResult.getTotalCount());
		
		return result;
	}
	
	private List<String> getContriesToSee() {
		List<String> countries = new ArrayList<>();
		
		List<SystemValue> countriesToSee = SessionData.getCountriesToSee();
		if (countriesToSee != null && countriesToSee.size() > 0) {
			for (SystemValue sys : countriesToSee) {
				countries.add(sys.getSystemCode());
			}
		}
		
		return countries;
	}

	/* (non-Javadoc)
	 * @see nl.infodation.emr.pricingservice.business.RuleBusiness#findRulesByIDs(java.util.List)
	 */
	@Override
	public List<DomainRule> findRulesByIDs(List<Long> IDs) {
		return DAOFactory.getDomainRuleDAO().findEntitiesByIDs(IDs);
	}

	/* (non-Javadoc)
	 * @see nl.infodation.emr.pricingservice.business.RuleBusiness#findRuleByNameAndCheck(java.lang.String, java.lang.Long, java.lang.String)
	 */
	@Override
	public DomainRule findRuleByNameAndCheck(String name, Integer environmentId, String checkName) {
		List<DomainRule> rules = DAOFactory.getDomainRuleDAO().findByName(name, environmentId);
		if (rules.size() == 1) {
			DomainRule domainRule = rules.get(0);
			if (domainRule != null) {
				// Process for role
				if (Constants.PROVEA_ROLE.equals(checkName)) {
					if (!domainRule.getBusLine().equals(Constants.PROVEA_ROLE)) {
						return null; // failed
					}
				} else if (Constants.AFM_ROLE.equals(checkName)) {
					if (!domainRule.getBusLine().equals(Constants.AFM_ROLE)) {
						return null; // failed
					}
				}
				return domainRule;
			}
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see nl.infodation.emr.pricingservice.business.RuleBusiness#existRuleName(java.lang.String)
	 */
	@Override
	public Integer existRuleName(String name) {
		return DAOFactory.getDomainRuleDAO().findByName(name).size();
	}

	/* (non-Javadoc)
	 * @see nl.infodation.emr.pricingservice.business.RuleBusiness#copyToEnvironment(java.lang.String, java.lang.String, int, java.lang.Boolean, java.util.List)
	 */
	@Override
	public Boolean copyToEnvironment(String superBusLine, String busLine,
			int environmentId, Boolean clean, List<Long> IDs) {
		Environment env = DAOFactory.getEnvironmentDAO().get(environmentId);
		return DAOFactory.getDomainRuleDAO().copyToEnvironment(superBusLine, busLine, env, clean, IDs);
	}

}
